"""
Video Utility Functions

Provides helper functions for video processing:
- Extract video frames as images
- Get video metadata
- Generate thumbnails
"""

import cv2
import numpy as np
from typing import Tuple, Optional
import logging

logger = logging.getLogger(__name__)


def get_video_frame(video_path: str, frame_number: int) -> Optional[np.ndarray]:
    """
    Extract a specific frame from video.

    Args:
        video_path: Path to video file
        frame_number: Frame number to extract (0-indexed)

    Returns:
        Frame as numpy array (RGB) or None if failed
    """
    try:
        cap = cv2.VideoCapture(video_path)

        if not cap.isOpened():
            logger.error(f"Failed to open video: {video_path}")
            return None

        # Set frame position
        cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number)

        # Read frame
        ret, frame = cap.read()
        cap.release()

        if not ret:
            logger.warning(f"Failed to read frame {frame_number} from {video_path}")
            return None

        # Convert BGR to RGB
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        return frame_rgb

    except Exception as e:
        logger.error(f"Error extracting frame: {e}")
        return None


def frame_to_jpeg(frame: np.ndarray, quality: int = 85) -> Optional[bytes]:
    """
    Convert frame to JPEG bytes.

    Args:
        frame: Frame as numpy array (RGB)
        quality: JPEG quality (0-100)

    Returns:
        JPEG bytes or None if failed
    """
    try:
        # Convert RGB to BGR for cv2
        frame_bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

        # Encode as JPEG
        encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), quality]
        ret, buffer = cv2.imencode('.jpg', frame_bgr, encode_param)

        if not ret:
            logger.error("Failed to encode frame as JPEG")
            return None

        return buffer.tobytes()

    except Exception as e:
        logger.error(f"Error converting frame to JPEG: {e}")
        return None


def get_video_metadata(video_path: str) -> dict:
    """
    Get video metadata.

    Args:
        video_path: Path to video file

    Returns:
        Dictionary with metadata
    """
    try:
        cap = cv2.VideoCapture(video_path)

        if not cap.isOpened():
            logger.error(f"Failed to open video: {video_path}")
            return {}

        metadata = {
            'total_frames': int(cap.get(cv2.CAP_PROP_FRAME_COUNT)),
            'fps': cap.get(cv2.CAP_PROP_FPS),
            'width': int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
            'height': int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)),
            'duration': int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) / cap.get(cv2.CAP_PROP_FPS)
        }

        cap.release()

        return metadata

    except Exception as e:
        logger.error(f"Error getting video metadata: {e}")
        return {}


def create_thumbnail(video_path: str, frame_number: int, size: Tuple[int, int] = (320, 180)) -> Optional[bytes]:
    """
    Create a thumbnail from video frame.

    Args:
        video_path: Path to video file
        frame_number: Frame number to use
        size: Thumbnail size (width, height)

    Returns:
        JPEG bytes of thumbnail or None if failed
    """
    frame = get_video_frame(video_path, frame_number)

    if frame is None:
        return None

    # Resize frame
    thumbnail = cv2.resize(frame, size, interpolation=cv2.INTER_AREA)

    return frame_to_jpeg(thumbnail, quality=75)
